package indi.qing.service.impl;

import com.alibaba.fastjson.JSONObject;
import indi.qing.common.Constant;
import indi.qing.common.GetHuaweiToken;
import indi.qing.common.JsonUtil;
import indi.qing.common.StreamClosedHttpResponse;
import indi.qing.entity.Device;
import indi.qing.mapper.DeviceMapper;
import indi.qing.mapper.SubDeviceMapper;
import indi.qing.service.DeviceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 熊卿智
 * @since 2021-12-15
 */
@Service
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements DeviceService {

    @Resource
    private DeviceMapper deviceMapper;

    @Resource
    private SubDeviceMapper subMapper;

    @Override
    public boolean switchControl(int state, Long deviceId) throws Exception {

        Device device = deviceMapper.selectById(deviceId);
        if(ObjectUtils.isEmpty(device))
            throw new RuntimeException("设备为空");

        String switchControlURI = Constant.BASE_URL + "/v5/iot/" + Constant.PROJECTID+ "/devices/"
                + device.getDeviceSn() + "/commands";

        String accessToken = GetHuaweiToken.login();

        Map<String, Object> paramCreateDeviceCommand = new HashMap<>();
        paramCreateDeviceCommand.put("service_id", "LightSwitchControl");
        paramCreateDeviceCommand.put("command_name", "Switch");
        Map<String, String> paras = new HashMap<>();
        String command ="";
        if (state == 1)     command="ON";
        if (state == 0)     command="OFF";
        paras.put("value", command);
        paramCreateDeviceCommand.put("paras", paras);
        String jsonRequest = JsonUtil.jsonObj2Sting(paramCreateDeviceCommand);

        try (CloseableHttpClient client = HttpClients.custom()
                .setSSLContext(new SSLContextBuilder().loadTrustMaterial(null,
                        (x509CertChain, authType) -> true).build())
                .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                .build()) {
            Date d = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String sj = sdf.format(d);
            System.out.println("Sent time: " + sj);
            HttpResponse responseCmdOrg = client.execute(RequestBuilder.create("POST")//请求方法POST
                    .setUri(switchControlURI)
                    .addHeader(HttpHeaders.CONTENT_TYPE, "application/json;charset=utf8")
                    .addHeader("X-Auth-Token", accessToken)
                    .setEntity(new StringEntity(jsonRequest)).build());
            StreamClosedHttpResponse responseCmd = new StreamClosedHttpResponse(responseCmdOrg);
            if (String.valueOf(responseCmd.getStatusLine().getStatusCode()).substring(0, 1).equals("2")) {
                System.out.println("Send command success");
            } else {
                System.out.println("Send command fail: ");
                System.out.println("Response:");
                System.out.println(responseCmd.toString());
                System.out.println(responseCmd.getContent());
                JSONObject resp = JSONObject.parseObject(responseCmd.getContent());
                throw new RuntimeException(resp.getString("error_msg"));
            }
        } catch (Exception e) {
            System.out.println("set command failed " + e.getMessage());
            throw new RuntimeException("命令下发失败"+ e.getMessage());
        }
        return false;
    }
    @Override
    public boolean LightControl(int luminance, Long deviceId) throws Exception {

        Device device = deviceMapper.selectById(deviceId);
        if(ObjectUtils.isEmpty(device)) {
            throw new RuntimeException("设备为空");
        }

        String lightControlURI = Constant.BASE_URL + "/v5/iot/" + Constant.PROJECTID+ "/devices/"
                + device.getDeviceSn() + "/commands";

        String accessToken = GetHuaweiToken.login();

        Map<String, Object> paramCreateDeviceCommand = new HashMap<>();
        paramCreateDeviceCommand.put("service_id", "LightControl");
        paramCreateDeviceCommand.put("command_name", "setLuminance");
        Map<String, Integer> paras = new HashMap<>();

        paras.put("value", luminance);
        paramCreateDeviceCommand.put("paras", paras);
        String jsonRequest = JsonUtil.jsonObj2Sting(paramCreateDeviceCommand);

        try (CloseableHttpClient client = HttpClients.custom()
                .setSSLContext(new SSLContextBuilder().loadTrustMaterial(null,
                        (x509CertChain, authType) -> true).build())
                .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                .build()) {
            Date d = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String sj = sdf.format(d);
            System.out.println("Sent time: " + sj);
            HttpResponse responseCmdOrg = client.execute(RequestBuilder.create("POST")//请求方法POST
                    .setUri(lightControlURI)
                    .addHeader(HttpHeaders.CONTENT_TYPE, "application/json;charset=utf8")
                    .addHeader("X-Auth-Token", accessToken)
                    .setEntity(new StringEntity(jsonRequest)).build());
            StreamClosedHttpResponse responseCmd = new StreamClosedHttpResponse(responseCmdOrg);
            if (String.valueOf(responseCmd.getStatusLine().getStatusCode()).substring(0, 1).equals("2")) {
                System.out.println("Send command success");
            } else {
                System.out.println("Send command fail: ");
                System.out.println("Response:");
                System.out.println(responseCmd.toString());
                System.out.println(responseCmd.getContent());
                JSONObject resp = JSONObject.parseObject(responseCmd.getContent());
                throw new RuntimeException(resp.getString("error_msg"));
            }
        } catch (Exception e) {
            System.out.println("set command failed " + e.getMessage());
            throw new RuntimeException("命令下发失败"+ e.getMessage());
        }
        return false;
    }

    @Override
    public List<Device> getDevices(Long userId) {
        List<Device> devices = lambdaQuery().eq(Device::getUserId, userId).list();
        if(CollectionUtils.isEmpty(devices)){
            throw new RuntimeException("你还未绑定台灯");
        }
        return devices;
    }
}
